package com.tyk.bookstore.back.member.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tyk.bookstore.back.common.core.model.page.PageVo;
import com.tyk.bookstore.back.common.core.util.AssertUtil;
import com.tyk.bookstore.back.common.core.util.ObjUtil;
import com.tyk.bookstore.back.member.model.entity.MemberDetailDo;
import com.tyk.bookstore.back.member.model.entity.MemberDo;
import com.tyk.bookstore.back.member.model.query.MemberPageQuery;
import com.tyk.bookstore.back.member.model.query.StateUpdateQuery;
import com.tyk.bookstore.back.member.model.result.MemberResultEnum;
import com.tyk.bookstore.back.member.model.vo.MemberPageVo;
import com.tyk.bookstore.back.member.model.vo.MemberVo;
import com.tyk.bookstore.back.member.repository.MemberDetailRepository;
import com.tyk.bookstore.back.member.repository.MemberRepository;
import com.tyk.bookstore.back.member.service.MemberService;
import com.tyk.bookstore.back.member.util.MapStructMember;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author tyk
 * @description 会员管理
 */
@Service
@RequiredArgsConstructor
public class MemberServiceImp implements MemberService {
    private final MemberRepository memberRepository;
    private final MemberDetailRepository memberDetailRepository;
    private final MapStructMember mapStructMember;

    @Override
    public MemberVo getById(Long id) {
        // 会员存在
        AssertUtil.isTrue(
                memberRepository.exist1Eq(
                        MemberDo::getId, id, MemberDo.class
                ),
                MemberResultEnum.MEMBER_NOT_FOUND
        );
        // 查询会员信息并返回
        return mapStructMember.toMemberVo(
                memberRepository.selectById(id),
                memberDetailRepository.selectById(id)
        );
    }


    @Override
    public MemberPageVo getPage(MemberPageQuery query) {

        Page<MemberDo> page = new Page<>(query.getPage(), query.getLimit());
        memberRepository.selectPage(page, buildMemberQueryWrapper(query));

        if (page.getTotal() == 0) return PageVo.instance(MemberPageVo.class);

        Map<Long, MemberDetailDo> mddMap = memberDetailRepository
                .selectByMemberIdList(page.getRecords().stream().map(MemberDo::getId).toList())
                .stream().collect(Collectors.toMap(MemberDetailDo::getMemberId, it -> it));

        MemberPageVo vo = mapStructMember.toMemberPageVo(page);

        vo.setRecords(
                page.getRecords().stream().map(
                                memberDo -> mapStructMember.toMemberPageVo$Member(
                                        memberDo, mddMap.get(memberDo.getId())
                                )
                        )
                        .toList());
        return vo;
    }

    @Override
    public void changeState(StateUpdateQuery query) {
        AssertUtil.isTrue(
                memberRepository.exist1Eq(
                        MemberDo::getId, query.getId(), MemberDo.class
                ),
                MemberResultEnum.MEMBER_NOT_FOUND
        );
        LambdaUpdateWrapper<MemberDo> wrapper = Wrappers.lambdaUpdate(MemberDo.class);
        wrapper.eq(MemberDo::getId, query.getId()).set(MemberDo::getState, query.getState());
        memberRepository.update(wrapper);
    }

    /**
     * 组装会员分页查询条件
     */
    private LambdaQueryWrapper<MemberDo> buildMemberQueryWrapper(MemberPageQuery query) {

        LambdaQueryWrapper<MemberDo> w1 = Wrappers.lambdaQuery(MemberDo.class);

        w1.eq(query.getState() != null, MemberDo::getState, query.getState());

        w1.like(ObjUtil.notBlank(query.getAccount()), MemberDo::getAccount, query.getAccount());

        w1.like(ObjUtil.notBlank(query.getPhone()), MemberDo::getPhone, query.getPhone());

        w1.like(ObjUtil.notBlank(query.getEmail()), MemberDo::getEmail, query.getEmail());

        w1.ge(query.getStartTime() != null, MemberDo::getCreateTime, query.getStartTime());
        w1.le(query.getEndTime() != null, MemberDo::getCreateTime, query.getEndTime());

        LambdaQueryWrapper<MemberDetailDo> w2 = Wrappers.lambdaQuery(MemberDetailDo.class);
        w2.like(ObjUtil.notBlank(query.getNickname()), MemberDetailDo::getNickname, query.getNickname());
        w2.eq(query.getGender() != null, MemberDetailDo::getGender, query.getGender());
        w2.like(ObjUtil.notBlank(query.getIdCard()), MemberDetailDo::getIdCard, query.getIdCard());
        w2.select(MemberDetailDo::getMemberId);
        List<Long> idList = memberDetailRepository.selectList(w2).stream().map(MemberDetailDo::getMemberId).toList();
        w1.in(MemberDo::getId, idList);

        w1.orderBy(true, false, MemberDo::getCreateTime);

        return w1;
    }

}
